package com.bigfans.api.clients;

import com.bigfans.Constants;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.exception.RemoteServiceRuntimeException;
import com.bigfans.framework.web.RequestHolder;
import com.bigfans.framework.web.RestResponseError;
import lombok.Data;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Data
public class ServiceRequest {

    protected RestTemplate restTemplate;

    public ServiceRequest(RestTemplate restTemplate , CurrentUser currentUser) {
        this.restTemplate = restTemplate;
        this.currentUser = currentUser;
        this.token = currentUser.generateToken(Constants.TOKEN.JWT_SECURITY_KEY);
    }

    private Map<String , String> headers = new HashMap<>();
    private CurrentUser currentUser;
    private String token;
    private String url;
    private List<Object> params;
    private String sourceService;
    private String targetService;

    protected void checkError(ResponseEntity responseEntity){
        HttpStatus statusCode = responseEntity.getStatusCode();
        if(statusCode.isError()){
            RestResponseError responseError = (RestResponseError)responseEntity.getBody();
            throw new RemoteServiceRuntimeException(responseError.getErrorCode() , responseError.getErrorMessage());
        }
    }

    public  <T> T get(Class<T> responseType ,String url , Object... params){
        HttpHeaders headers = new HttpHeaders();
        headers.put(Constants.TOKEN.HEADER_KEY_NAME , Arrays.asList(token));
        HttpEntity requestEntity = new HttpEntity(null, headers);
        UriComponents builder = UriComponentsBuilder.fromUriString(url).build().expand(params).encode();
        ResponseEntity<Map> responseEntity = restTemplate.exchange(builder.toUri(), HttpMethod.GET, requestEntity, Map.class);
        checkError(responseEntity);
        Map resp = responseEntity.getBody();
        return (T)resp.get("data");
    }

    public void post(String url , Object payload , Object ... params){
        this.post(null , url , payload , params);
    }

    public <T> T post(Class<T> responseType , String url , Object payload , Object ... params){
        HttpHeaders headers = new HttpHeaders();
        headers.put(Constants.TOKEN.HEADER_KEY_NAME, Arrays.asList(token));
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));

        HttpEntity requestEntity = new HttpEntity(payload, headers);

        UriComponents builder = UriComponentsBuilder.fromUriString(url).build().expand(params).encode();
        ResponseEntity<Map> responseEntity = restTemplate.exchange(builder.toUri(), HttpMethod.POST, requestEntity, Map.class);
        if(responseType == null){
            return null;
        }
        Map resp = responseEntity.getBody();
        return (T)resp.get("data");
    }
}
